package com.duojuhe.aspect;


import cn.hutool.core.text.StrFormatter;
import com.duojuhe.common.annotation.DataScopeFilter;
import com.duojuhe.common.bean.DataScopeFilterBean;
import com.duojuhe.common.bean.UserTokenInfoVo;
import com.duojuhe.cache.LoginUserTokenCache;
import com.duojuhe.common.constant.DataScopeConstants;
import com.duojuhe.common.constant.SingleStringConstant;
import com.duojuhe.common.constant.SystemConstants;
import com.duojuhe.common.enums.SystemEnum;
import com.duojuhe.common.enums.user.UserEnum;

import com.duojuhe.coremodule.system.entity.SystemDept;
import com.duojuhe.coremodule.system.entity.SystemRole;
import com.duojuhe.coremodule.system.mapper.SystemDeptMapper;
import com.duojuhe.coremodule.system.mapper.SystemRoleMapper;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;


/**
 * 数据过滤处理
 * 
 * @author eavan
 */
@Aspect
@Component
public class DataScopeFilterAspect {
    @Resource
    private SystemRoleMapper systemRoleMapper;
    @Resource
    private SystemDeptMapper systemDeptMapper;

    @Pointcut("execution(* com.duojuhe..*.*(..))")
    public void dataScopePointCut() {

    }

    @Before("(dataScopePointCut() && @annotation(dataScopeFilter))")
    public void doBefore(JoinPoint joinPoint, DataScopeFilter dataScopeFilter) {
        dataScopeFilter(joinPoint,dataScopeFilter);
    }

    /**
     * 数据范围过滤
     * 
     * @param joinPoint 切点
     * @param dataScopeFilter
     */
    public void dataScopeFilter(JoinPoint joinPoint,DataScopeFilter dataScopeFilter) {
        //租户id别名
        String tenantIdAlias = dataScopeFilter.tenantId();
        //部门id别名
        String deptIdAlias = dataScopeFilter.deptId();
        //用户id别名
        String userIdAlias = dataScopeFilter.userId();
        //数据过滤目标id别名
        String filterTargetId = dataScopeFilter.filterTargetId();
        //未知标识
        String unknownId = "unknownId";
        // 获取当前的用户
        UserTokenInfoVo currentUser = LoginUserTokenCache.getCurrentLoginUserInfoDTO();
        //用户角色ID
        String roleId = StringUtils.isNotBlank(currentUser.getRoleId())?currentUser.getRoleId():unknownId;
        //租户id
        String tenantId = StringUtils.isNotBlank(currentUser.getTenantId())?currentUser.getTenantId():unknownId;
        //岗位id
        String postId = StringUtils.isNotBlank(currentUser.getPostId())?currentUser.getPostId():unknownId;
        //用户类型
        String userTypeCode = currentUser.getUserTypeCode();
        //用户数据范围
        String dataScope;
        if(StringUtils.isNotBlank(dataScopeFilter.dataScope())){
            dataScope = dataScopeFilter.dataScope();
        }else{
            if (UserEnum.USER_TYPE.SUPER_ADMIN.getKey().equals(userTypeCode)||
                    UserEnum.USER_TYPE.TENANT_ADMIN.getKey().equals(userTypeCode)){
                dataScope = DataScopeConstants.TENANT_ALL_DATA;
            }else{
                //获取当前用户的角色
                if (!unknownId.equals(roleId)){
                    SystemRole systemRole = systemRoleMapper.selectByPrimaryKey(roleId);
                    dataScope = systemRole==null?DataScopeConstants.SELF_DATA:systemRole.getDataScopeCode();
                }else {
                    dataScope = DataScopeConstants.SELF_DATA;
                }
            }
        }
        //最终拼接sql字符串
        StringBuilder sqlString = new StringBuilder();
        //用户自己的所在部门ID
        String deptId = StringUtils.isNotBlank(currentUser.getCreateDeptId())?currentUser.getCreateDeptId():unknownId;
        //用户ID
        String userId = currentUser.getUserId();
        //用户数据范围编码
        if (DataScopeConstants.ALL_DATA.equals(dataScope)){
            //全系统全部数据
        }else if (DataScopeConstants.TENANT_ALL_DATA.equals(dataScope)){
            //租户全部数据
            sqlString.append(StrFormatter.format(" and {} = '{}' ", tenantIdAlias, tenantId));
        }else if (DataScopeConstants.CUSTOM_DATA.equals(dataScope)){
            //自定义数据权限
            sqlString.append(StrFormatter.format(" and {}  in (select dept_id from system_role_dept where role_id = '{}' )", deptIdAlias, roleId));
        }else if (DataScopeConstants.SELF_DEPT.equals(dataScope)) {
            //自己部门数据权限
            sqlString.append(StrFormatter.format(" and {} = '{}' ", deptIdAlias, deptId));
        }else if (DataScopeConstants.SELF_DEPT_SUBORDINATE.equals(dataScope)) {
            //本部门及以下数据 //查询本部门及以下部门id集合
            SystemDept systemDept= systemDeptMapper.selectByPrimaryKey(deptId);
            //从缓存中查询数据
            //List<String> deptIdList = getDeptIdList();
            //String ids = deptIdList.stream().map(s -> "'" + s + "'").collect(Collectors.joining(","));
            if (systemDept!=null){
                //机构层级路径，查询向下的部门数据
                String deptPath = systemDept.getDeptPath();
                sqlString.append(StrFormatter.format(" and {}  in (select dept_id from system_dept where like '{}%' )", deptIdAlias, deptPath));
            }else{
                sqlString.append(StrFormatter.format(" and {} = '{}' ", deptIdAlias, unknownId));
            }
        } else if (DataScopeConstants.SELF_DATA.equals(dataScope)){
            //查询自己的数据
            if (StringUtils.isNotBlank(userIdAlias)){
                sqlString.append(StrFormatter.format(" and {} = '{}' ", userIdAlias, userId));
            }else{
                // 数据权限为仅本人且没有userIdAlias别名不查询任何数据
                sqlString.append(StrFormatter.format(" and {} = '{}' ", userIdAlias, unknownId));
            }
        }else{
            sqlString.append(StrFormatter.format(" and {} = '{}' ", userIdAlias, unknownId));
        }
        //开启了数据允许范围权限
        if (StringUtils.isNotBlank(filterTargetId)){
            List<String> relationIdList = new ArrayList<>();
            //部门id
            if (!unknownId.equals(deptId)&&!SystemConstants.UNKNOWN_ID.equals(deptId)) {
                relationIdList.add(deptId);
            }
            //角色id
            if (!unknownId.equals(roleId)&&!SystemConstants.UNKNOWN_ID.equals(roleId)) {
                relationIdList.add(roleId);
            }
            //岗位id
            if (!unknownId.equals(postId)&&!SystemConstants.UNKNOWN_ID.equals(postId)){
                relationIdList.add(postId);
            }
            //用户id
            relationIdList.add(userId);
            String ids = relationIdList.stream().map(s -> "'" + s + "'").collect(Collectors.joining(SingleStringConstant.COMMA));
            //所有权限
            String allData = SystemEnum.DATA_ALLOW_AUTH.ALL_AUTH.getKey();
            sqlString.append(StrFormatter.format(" and ( {} = '"+allData+"' or {} in (select target_id from system_data_filter where relation_id in ( {} )))", filterTargetId,filterTargetId, ids));
        }

        if (joinPoint.getArgs().length>0){
            for (Object params:joinPoint.getArgs()){
                if (params instanceof DataScopeFilterBean) {
                    DataScopeFilterBean filterBean = (DataScopeFilterBean) params;
                    filterBean.setDataScopeFilter(sqlString.toString());
                    break;
                }
            }
        }
    }

    public static void main(String[] args) {
        List<String> relationIdList = new ArrayList<>();
        relationIdList.add("deptId");//部门id
        relationIdList.add("roleId");//角色id
        relationIdList.add("userId");//用户id
        String filterTargetId = "t.ss";
        String ids = relationIdList.stream().map(s -> "'" + s + "'").collect(Collectors.joining(","));
        String allData = SystemEnum.DATA_ALLOW_AUTH.ALL_AUTH.getKey();
        System.out.println(StrFormatter.format(" and ( {} = '"+allData+"' or {} in (select target_id from system_data_filter where relation_id in ( {} )))", filterTargetId,filterTargetId, ids));
    }
}
